use anyhow::anyhow;
use jsonwebtoken::{Algorithm, DecodingKey, EncodingKey, Header, Validation};
use serde::{Deserialize, Serialize};

use crate::errors;

const SECRET_KEY: &[u8] = b"dAS{DK_(!jrdf9J()!@JR()wjs9dj1-9q1j(_JR_@!(rjw-qj1-9jf_(J!_@(Ej-92";

#[derive(Deserialize, Serialize, Debug)]
pub struct Claims {
    exp: i64,
    nonce: String,
}

pub fn encode(nonce: String) -> Result<String, anyhow::Error> {
    let claims = Claims {
        exp: chrono::offset::Utc::now()
            .checked_add_signed(chrono::Duration::days(3))
            .expect("pizda")
            .timestamp(),
        nonce,
    };

    match jsonwebtoken::encode(
        &Header::new(Algorithm::HS256),
        &claims,
        &EncodingKey::from_secret(SECRET_KEY),
    ) {
        Ok(target) => Ok(target),
        Err(err) => Err(anyhow!("Пиздец какой-то произошел {}", err)),
    }
}

pub fn decode(token: String, nonce: &String) -> Result<Claims, errors::Error> {
    let token = match jsonwebtoken::decode::<Claims>(
        &token,
        &DecodingKey::from_secret(SECRET_KEY),
        &Validation::new(Algorithm::HS256),
    ) {
        Ok(data) => data,
        Err(err) => return Err(errors::Error::JWTToken),
    };

    println!("{:?}", token.claims);

    if nonce == &token.claims.nonce {
        return Ok(token.claims);
    }

    Err(errors::Error::WrongCredentials)
}
